/*
 * This file defines the functions and data structures 
 * relating to calculating player stats and parsing the batting.txt file
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME_LENGTH 20
#define NUMBER_OF_PLAYERS 29

// Structures

// Represents a cricket players statistics
struct stats{
	int batting_average; //The total number of runs divided by the total number of innings in which the batsman was out. Ave = Runs/[I - NO] 
	int centuries; // The number of innings in which the batsman scored one hundred runs or more.
	int half_centuries; // The number of innings in which the batsman scored fifty to ninety-nine runs (centuries do not count as half-centuries as well).
	int balls_faced; //Balls Faced (BF): The total number of balls received, including no balls but not including wides.
	int strike_rate; //Strike Rate (SR): The number of runs scored per 100 balls faced. (SR = [100 * Runs]/BF)
};

// Represents a cricket player
struct cricket_player{
	char name[NAME_LENGTH];
	char country[3]; // Contains a country code
	int innings;
	int runs;
	int times_not_out;
	int highest_score;
	int highest_score_is_not_out; // Boolean
	float batting_average; //The total number of runs divided by the total number of innings in which the batsman was out. Ave = Runs/[I - NO] 
	int times_queried;
} players[NUMBER_OF_PLAYERS];
//global var
int count;
// Method defenitions
void init();
void calculate_stats();
int get_player(const char* player_name,struct cricket_player *player);

// Method declerations
void init(){
	FILE *file;
	char *mode = "rt";
	char outputFilename[] = "battings.txt";
	char delimiter = ';';

	// Open the file
	file = fopen(outputFilename, mode);

	if (file == NULL) {
		fprintf(stderr, "Can't open output file %s!\n", outputFilename);
		exit(1);
	}

	// parse the file
  	int  buffer_size = 200;
	count = 0;
  	char line_buffer[buffer_size];  
  	while( fgets(line_buffer, buffer_size, file) != NULL ){      
		struct cricket_player player;		
		
		// clean player char arrays TODO extract method
		int g;
		for(g = 0; g < NAME_LENGTH; g++){
			player.name[g] = '\0';
		}

		for(g = 0; g < NAME_LENGTH; g++){
			player.country[g] = '\0';
		}
	
		if(line_buffer[0] != '#'){
			char *ptr = line_buffer;
			char field [32];

			int n;
			int coloumn = 1;
			while ( sscanf(ptr, "%31[^;]%n", field, &n) == 1 ){
				if(coloumn == 1){ 
					int a;
					for(a = 0; a < strlen(field); a++)
						player.name[a] = field[a];							
				} 						
				else if(coloumn == 2){ 
					int a;
					for(a = 0; a < strlen(field); a++)
						player.country[a] = field[a];							
				} 
				else if(coloumn == 3){ 
					player.innings = atoi(field);
				}							
				else if(coloumn == 4){ 
					player.runs = atoi(field);
				}							
				else if(coloumn == 5){ 
					player.times_not_out = atoi(field);
				}							
				else if(coloumn == 6){ 
					player.highest_score = atoi(field);
				}	
				else if(coloumn == 7){
					if(strcmp("TRUE", field) == 0){
						player.highest_score_is_not_out = 1;
					}
					else if(strcmp(field, "FALSE") == 0){ 
						player.highest_score_is_not_out = 0;
					}
				}						
											
				ptr += n; 
				coloumn++;

				if ( *ptr != delimiter ){
					break; 
				}

				++ptr; 
			}
			
			//Calculate stats
			printf("Variables: %d, %d, %d\n", player.runs, player.innings, player.times_not_out);		
			float factor = (player.innings - player.times_not_out);
			if(factor > 0)			
				player.batting_average = player.runs/factor;
			else
				player.batting_average = player.runs/1;
				player.times_queried = 0;
			players[count] = player;
			count++;
      	}
	}
    
  	//Close the file
  	fclose(file);
}

int get_player(const char * player_name , struct cricket_player * player){
	int i;
	for(i = 0; i < count; i++){
		if((strcmp(players[i].name, player_name)) == 0)
		{
			players[i].times_queried++;
			*player = players[i];
			
			return 1;
		}
	}
	return 0;
}

/* Only for testing */
/*int main(void){
	char name[] = "Adams";

	init();
	get_player(name);
	struct cricket_player player;
	player = get_player(name);

	printf("\n|------------- Player %s ----------------------|\n", player.name);
	printf("Players country: %s\n", 					player.country);
	printf("Players innings: %d\n", 					player.innings);
	printf("Players runs: %d\n",	 					player.runs);
	printf("Players times_not_out: %d\n",				player.times_not_out);
	printf("Players highest_score: %d\n", 				player.highest_score);
	printf("Players highest_score_is_not_out: %d\n", 	player.highest_score_is_not_out);
	printf("Players batting average: %f\n", 			player.batting_average);
	
	exit(EXIT_SUCCESS);
}*/

/*
Statistics::

Innings (I): The number of innings in which the batsman actually batted.

Not outs (NO): The number of times the batsman was not out at the conclusion of an innings they batted in.1

Runs (R): The number of runs scored.

Highest Score (HS/Best): The highest score ever made by the batsman.

Batting Average (Ave): The total number of runs divided by the total number of innings in which the batsman was out. Ave = Runs/[I - NO] (also Avge or Avg.)

Centuries (100): The number of innings in which the batsman scored one hundred runs or more.

Half-centuries (50): The number of innings in which the batsman scored fifty to ninety-nine runs (centuries do not count as half-centuries as well).

Balls Faced (BF): The total number of balls received, including no balls but not including wides.

Strike Rate (SR): The number of runs scored per 100 balls faced. (SR = [100 * Runs]/BF)

 

1 Batsmen who are not required to bat in a particular innings (due to victory or declaration) are not considered "Not Out" in that innings. 
Only the player/s who have taken to the crease and remained there until the completion of an innings, are marked "Not Out" on the scorecard.

For statistical purposes, batsmen who retire due to injury or illness are also deemed not out [1], while batsmen who retire for any other 
reason are deemed out [2], except in exceptional circumstances (in 1983 Gordon Greenidge, not out on 154, departed a Test match to be with 
his daughter, who was ill and subsequently died - he was subsequently deemed not out [3] the only such decision in the history of Test cricket)

*/
